//    Copyright (c) 2009 Elwyn Malethan
//
//    This file is part of SeemoreJ.
//
//    SeemoreJ is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    SeemoreJ is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.

//    You should have received a copy of the GNU General Public License
//    along with SeemoreJ.  If not, see <http://www.gnu.org/licenses/>.

package com.malethan.seemorej.taglib;

import com.malethan.seemorej.taglib.elements.Select;
import com.malethan.seemorej.taglib.elements.LabelValueBean;

import java.util.GregorianCalendar;
import java.util.Date;
import java.util.Calendar;
import java.util.ArrayList;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class DateSelectTag extends ElementTag {
    //----------------------------------------------------------------------- Static Properties and Constants

    private static final Log log = LogFactory.getLog(DateSelectTag.class);

    //----------------------------------------------------------------------- Static Methods
    //----------------------------------------------------------------------- Instance Properties

    private GregorianCalendar gc;

    private String mode = "datetime";

    //----------------------------------------------------------------------- Constructors
    //----------------------------------------------------------------------- Getters and Setters

    public void setMode(String mode) {
        this.mode = mode;
    }

    //----------------------------------------------------------------------- Instance Methods

    //TODO: This seems inelegant and crap. Refactor to make it "right" 
    protected String constructElement() {
        gc = new GregorianCalendar();
//        try {
//            gc.setTime(new SimpleDateFormat(format).parse(value));
//        } catch (ParseException e) {
//            log.error("Failed to parse a date using " + format + ", reverting to today", e);
//            gc.setTime(new Date());
//        }
        if (value != null && value instanceof Date) {
            gc.setTime((Date) value);
        } else {
            log.warn("value is null or not a java.util.Date");
            gc.setTime(new Date());
        }

        if (mode == null || !mode.matches("^(date|time|datetime)$")) {
            mode = "datetime";
        }

        StringBuffer html = new StringBuffer();

        if (mode.matches("^(date|datetime)$")) {
            html.append(new Select() {{
                setHtmlId(htmlId + "_year");
                setHtmlClass("dateselect year");
                setName(name + "_year");
                setValue(String.format("%04d", gc.get(Calendar.YEAR)));
                setOptions(new ArrayList<LabelValueBean>() {{
                    int start = gc.get(Calendar.YEAR) - 10;
                    int end = gc.get(Calendar.YEAR) + 10;

                    for (int year = start; year <= end; year++) {
                        String yearString = String.format("%04d", year);
                        add(new LabelValueBean(yearString, yearString));
                    }
                }});
            }}.toString());

            html.append("-");

            //TODO: Replace with month names
            html.append(new Select() {{
                setHtmlId(htmlId + "_month");
                setHtmlClass("dateselect month");
                setName(name + "_month");
                setValue(String.format("%02d", gc.get(Calendar.MONTH) + 1));
                setOptions(new ArrayList<LabelValueBean>() {{
                    for (int month = 0; month < 12; month++) {
                        add(new LabelValueBean(String.format("%02d", month+1), String.format("%02d", month+1)));
                    }
                }});
            }}.toString());

            html.append("-");

            html.append(new Select() {{
                setHtmlId(htmlId + "_day");
                setHtmlClass("dateselect day");
                setName(name + "_day");
                setValue(String.format("%02d", gc.get(Calendar.DATE)));
                setOptions(new ArrayList<LabelValueBean>() {{
                    for (int day = 0; day <= 31; day++) {
                        add(new LabelValueBean(String.format("%02d", day), String.format("%02d", day)));
                    }
                }});
            }}.toString());
        }

        if (mode.matches("^(time|datetime)$")) {
            html.append(" ");
            html.append(new Select() {{
                setHtmlId(htmlId + "_hour");
                setHtmlClass("dateselect hour");
                setName(name + "_hour");
                setValue(String.format("%02d", gc.get(Calendar.HOUR_OF_DAY)));
                setOptions(new ArrayList<LabelValueBean>() {{
                    for (int day = 0; day < 24; day++) {
                        add(new LabelValueBean(String.format("%02d", day), String.format("%02d", day)));
                    }
                }});
            }}.toString());

            html.append(":");

            html.append(new Select() {{
                setHtmlId(htmlId + "_minute");
                setHtmlClass("dateselect minute");
                setName(name + "_minute");
                setValue(String.format("%02d", gc.get(Calendar.MINUTE)));
                setOptions(new ArrayList<LabelValueBean>() {{
                    for (int day = 0; day < 60; day++) {
                        add(new LabelValueBean(String.format("%02d", day), String.format("%02d", day)));
                    }
                }});
            }}.toString());

            html.append(":");

            html.append(new Select() {{
                setHtmlId(htmlId + "_second");
                setHtmlClass("dateselect second");
                setName(name + "_second");
                setValue(String.format("%02d", gc.get(Calendar.SECOND)));
                setOptions(new ArrayList<LabelValueBean>() {{
                    for (int day = 0; day < 60; day++) {
                        add(new LabelValueBean(String.format("%02d", day), String.format("%02d", day)));
                    }
                }});
            }}.toString());
        }

        return html.toString();
    }

    public void release() {
        super.release();
        this.mode = "datetime";
    }
}
